#include "mapdialog.h"
#include "ui_mapdialog.h"
#include <QtGui>
#include <mapdialog.h>
#include <QBool>
#include <QTcpSocket>
#include <QGraphicsPixmapItem>
#include "station.h"
#include <QGraphicsSimpleTextItem>
#include <QGraphicsItemGroup>
#include <QMessageBox>
#include <QMouseEvent>

int MAP_HEIGHT = 1800;
int MAP_WIDTH = 3600;
int HALF_MAP_HEIGHT = 900;
int HALF_MAP_WIDTH = 1800;

MapDialog::MapDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MapDialog)
{
    ui->setupUi(this);
    this->setWindowTitle("Press z to zoom in and x to zoom out. Use arrows and mouse to pan.");

    ZoomLevel = 1.0;

    background = new QPixmap(":/new/icons/icons/map.png");

    //scene = new QGraphicsScene(this);
    scene = new aprsGraphicsScene(this);
    //scene = new QGraphicsScene(this);

    ui->MapView->setScene(scene);
    ui->MapView->setDragMode(QGraphicsView::ScrollHandDrag);
    ui->MapView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    ui->MapView->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    scene->addPixmap(*background);
}

void MapDialog::ZoomIn()
{
    ui->MapView->scale(2.0, 2.0);    
    ZoomLevel = ZoomLevel * 0.5;
    foreach(basicStation* zoomInStation, scene->qlist)
    {
        zoomInStation->pixmapItem->scale(0.5, 0.5);
    }
}

void MapDialog::ZoomOut()
{
    ui->MapView->scale(0.5, 0.5);
    ZoomLevel = ZoomLevel * 2.0;
    foreach(basicStation* zoomOutStation, scene->qlist)
    {
        zoomOutStation->pixmapItem->scale(2.0, 2.0);        
    }
}

void MapDialog::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Z)
    {
        ZoomIn();
    }
    else if(event->key() == Qt::Key_X)
    {
        ZoomOut();
    }
}

void MapDialog::plotActualStation(QString callsign, char symbolTable, char symbolCode, float lat, float lon)
{

    QPointF *location  = new QPointF(lon, lat);
    QPointF PixelLocation = ConvertPixToLatLon(location);

    foreach(basicStation* DrawnStation, scene->qlist)
    {
        if(callsign == DrawnStation->callsign)
        {
            qDebug() << "Duplicate station detected!";
            qreal oldLon = DrawnStation->pixmapItem->x();
            qreal oldLat = DrawnStation->pixmapItem->y();
            scene->qlist.removeOne(DrawnStation);
            scene->removeItem(DrawnStation->pixmapItem);

            if(oldLon != PixelLocation.x() || oldLat != PixelLocation.y())
            {
                QGraphicsLineItem *line = new QGraphicsLineItem();
                line->setLine(oldLon, oldLat, PixelLocation.x(), PixelLocation.y());

                scene->addItem(line);
                DrawnStation->traceList.append(line);
            }
        }
    }

    QString StationTypeString = GetStationType(symbolTable, symbolCode);
    QPixmap icon = QPixmap(StationTypeString);

    QGraphicsPixmapItem *Station = new QGraphicsPixmapItem();
    Station->setPixmap(icon);
    Station->setX(PixelLocation.x());
    Station->setY(PixelLocation.y());
    Station->setAcceptedMouseButtons(Qt::RightButton);

    basicStation *plotStation = new basicStation();
    plotStation->callsign = callsign;
    plotStation->pixmapItem = Station;
    plotStation->LonLat = QPointF(location->x(), location->y());

    plotStation->pixmapItem->scale(ZoomLevel, ZoomLevel);

    scene->qlist.append(plotStation);
    scene->addItem(plotStation->pixmapItem);
}


//Checks for the primary or alt tables. If not in either, draw them as a tractor
QString MapDialog::GetStationType(char table, char code)
{
    QString type = "";

    //Primary Table Types Here
    if(table == '/')
    {
        switch(code)
        {
        case '!':
            type = ":/new/icons/icons/1.png";
            break;

        case '#':
            type = ":/new/icons/icons/3.png";
            break;

        case '$':
            type = ":/new/icons/icons/4.png";
            break;

        case '%':
            type = ":/new/icons/icons/93.png";
            break;

        case '&':
            type = ":/new/icons/icons/5.png";
            break;

        case 0x27:
            type = ":/new/icons/icons/6.png";
            break;

        case '(':
            type = ":/new/icons/icons/7.png";
            break;

        case '*':
            type = ":/new/icons/icons/9.png";
            break;

        case '+':
            type = ":/new/icons/icons/10.png";
            break;

        case ',':
            type = ":/new/icons/icons/11.png";
            break;

        case '-':
            type = ":/new/icons/icons/12.png";
            break;

        case '.':
            type = ":/new/icons/icons/13.png";
            break;

        case '/':
            type = ":/new/icons/icons/14.png";
            break;

        case '0':
            type = ":/new/icons/icons/15.png";
            break;

        case '1':
            type = ":/new/icons/icons/16.png";
            break;

        case '2':
            type = ":/new/icons/icons/17.png";
            break;

        case '3':
            type = ":/new/icons/icons/18.png";
            break;

        case '4':
            type = ":/new/icons/icons/19.png";
            break;

        case '5':
            type = ":/new/icons/icons/20.png";
            break;

        case '6':
            type = ":/new/icons/icons/21.png";
            break;

        case '7':
            type = ":/new/icons/icons/22.png";
            break;

        case '8':
            type = ":/new/icons/icons/23.png";
            break;

        case '9':
            type = ":/new/icons/icons/24.png";
            break;

        case ':':
            type = ":/new/icons/icons/25.png";
            break;

        case ';':
            type = ":/new/icons/icons/26.png";
            break;

        case '<':
            type = ":/new/icons/icons/27.png";
            break;

        case '=':
            type = ":/new/icons/icons/28.png";
            break;

        case '>':
            type = ":/new/icons/icons/29.png";
            break;

        case '?':
            type = ":/new/icons/icons/30.png";
            break;

        case '@':
            type = ":/new/icons/icons/31.png";
            break;

        case 'A':
            type = ":/new/icons/icons/32.png";
            break;

        case 'B':
            type = ":/new/icons/icons/33.png";
            break;

        case 'C':
            type = ":/new/icons/icons/34.png";
            break;

        case 'E':
            type = ":/new/icons/icons/35.png";
            break;

        case 'G':
            type = ":/new/icons/icons/37.png";
            break;

        case 'H':
            type = ":/new/icons/icons/38.png";
            break;

        case 'I':
            type = ":/new/icons/icons/39.png";
            break;

        case 'K':
            type = ":/new/icons/icons/41.png";
            break;

        case 'M':
            type = ":/new/icons/icons/43.png";
            break;

        case 'N':
            type = ":/new/icons/icons/44.png";
            break;

        case 'O':
            type = ":/new/icons/icons/45.png";
            break;

        case 'P':
            type = ":/new/icons/icons/46.png";
            break;

        case 'R':
            type = ":/new/icons/icons/48.png";
            break;

        case 'S':
            type = ":/new/icons/icons/49.png";
            break;

        case 'T':
            type = ":/new/icons/icons/50.png";
            break;

        case 'U':
            type = ":/new/icons/icons/51.png";
            break;

        case 'V':
            type = ":/new/icons/icons/27.png";
            break;

        case 'W':
            type = ":/new/icons/icons/53.png";
            break;

        case 'X':
            type = ":/new/icons/icons/54.png";
            break;

        case 'Y':
            type = ":/new/icons/icons/55.png";
            break;

        case 'Z':
            type = ":/new/icons/icons/56.png";
            break;

        case '[':
            type = ":/new/icons/icons/57.png";
            break;

        case '\\':
            type = ":/new/icons/icons/58.png";
            break;

        case ']':
            type = ":/new/icons/icons/59.png";
            break;

        case '^':
            type = ":/new/icons/icons/60.png";
            break;

        case '_':
            type = ":/new/icons/icons/61.png";
            break;

        case '`':
            type = ":/new/icons/icons/62.png";
            break;

        case 'a':
            type = ":/new/icons/icons/63.png";
            break;

        case 'b':
            type = ":/new/icons/icons/64.png";
            break;

        case 'd':
            type = ":/new/icons/icons/66.png";
            break;

        case 'e':
            type = ":/new/icons/icons/67.png";
            break;

        case 'f':
            type = ":/new/icons/icons/68.png";
            break;

        case 'g':
            type = ":/new/icons/icons/69.png";
            break;

        case 'h':
            type = ":/new/icons/icons/70.png";
            break;

        case 'i':
            type = ":/new/icons/icons/71.png";
            break;

        case 'j':
            type = ":/new/icons/icons/72.png";
            break;

        case 'k':
            type = ":/new/icons/icons/73.png";
            break;

        case 'm':
            type = ":/new/icons/icons/75.png";
            break;

        case 'n':
            type = ":/new/icons/icons/76.png";
            break;

        case 'o':
            type = ":/new/icons/icons/77.png";
            break;

        case 'p':
            type = ":/new/icons/icons/78.png";
            break;

        case 'q':
            type = ":/new/icons/icons/79.png";
            break;

        case 'r':
            type = ":/new/icons/icons/80.png";
            break;

        case 's':
            type = ":/new/icons/icons/81.png";
            break;

        case 't':
            type = ":/new/icons/icons/82.png";
            break;

        case 'u':
            type = ":/new/icons/icons/83.png";
            break;

        case 'v':
            type = ":/new/icons/icons/84.png";
            break;

        case 'w':
            type = ":/new/icons/icons/85.png";
            break;

        case 'x':
            type = ":/new/icons/icons/86.png";
            break;

        case 'y':
            type = ":/new/icons/icons/90.png";
            break;
        }
    }
    //Alt table types here
    else
    {
        switch(code)
        {
        case '!':
            type = ":/new/icons/icons/97.png";
            break;

        case '#':
            type = ":/new/icons/icons/99.png";
            break;

        case '$':
            type = ":/new/icons/icons/100.png";
            break;

        case '&':
            type = ":/new/icons/icons/102.png";
            break;

        case 0x27:
            type = ":/new/icons/icons/6.png";
            break;

        case '(':
            type = ":/new/icons/icons/104.png";
            break;

        case '*':
            type = ":/new/icons/icons/106.png";
            break;

        case '+':
            type = ":/new/icons/icons/107.png";
            break;

        case ',':
            type = ":/new/icons/icons/108.png";
            break;

        case '-':
            type = ":/new/icons/icons/109.png";
            break;

        case '.':
            type = ":/new/icons/icons/110.png";
            break;

        case '0':
            type = ":/new/icons/icons/112.png";
            break;

        case '9':
            type = ":/new/icons/icons/121.png";
            break;

        case ':':
            type = ":/new/icons/icons/122.png";
            break;

        case ';':
            type = ":/new/icons/icons/123.png";
            break;

        case '<':
            type = ":/new/icons/icons/124.png";
            break;

        case '>':
            type = ":/new/icons/icons/126.png";
            break;

        case '?':
            type = ":/new/icons/icons/127.png";
            break;

        case '@':
            type = ":/new/icons/icons/128.png";
            break;

        case 'A':
            type = ":/new/icons/icons/129.png";
            break;

        case 'B':
            type = ":/new/icons/icons/130.png";
            break;

        case 'C':
            type = ":/new/icons/icons/131.png";
            break;

        case 'D':
            type = ":/new/icons/icons/132.png";
            break;

        case 'E':
            type = ":/new/icons/icons/133.png";
            break;

        case 'F':
            type = ":/new/icons/icons/134.png";
            break;

        case 'G':
            type = ":/new/icons/icons/135.png";
            break;

        case 'H':
            type = ":/new/icons/icons/136.png";
            break;

        case 'I':
            type = ":/new/icons/icons/137.png";
            break;

        case 'K':
            type = ":/new/icons/icons/139.png";
            break;

        case 'L':
            type = ":/new/icons/icons/140.png";
            break;

        case 'N':
            type = ":/new/icons/icons/142.png";
            break;

        case 'P':
            type = ":/new/icons/icons/144.png";
            break;

        case 'Q':
            type = ":/new/icons/icons/145.png";
            break;

        case 'R':
            type = ":/new/icons/icons/146.png";
            break;

        case 'S':
            type = ":/new/icons/icons/147.png";
            break;

        case 'T':
            type = ":/new/icons/icons/148.png";
            break;

        case 'U':
            type = ":/new/icons/icons/149.png";
            break;

        case 'V':
            type = ":/new/icons/icons/150.png";
            break;

        case 'W':
            type = ":/new/icons/icons/151.png";
            break;

        case 'X':
            type = ":/new/icons/icons/152.png";
            break;

        case '[':
            type = ":/new/icons/icons/155.png";
            break;

        case '^':
            type = ":/new/icons/icons/158.png";
            break;

        case '_':
            type = ":/new/icons/icons/159.png";
            break;

        case '`':
            type = ":/new/icons/icons/160.png";
            break;

        case 'a':
            type = ":/new/icons/icons/161.png";
            break;

        case 'b':
            type = ":/new/icons/icons/162.png";
            break;

        case 'c':
            type = ":/new/icons/icons/163.png";
            break;

        case 'd':
            type = ":/new/icons/icons/164.png";
            break;

        case 'e':
            type = ":/new/icons/icons/165.png";
            break;

        case 'f':
            type = ":/new/icons/icons/166.png";
            break;

        case 'g':
            type = ":/new/icons/icons/167.png";
            break;

        case 'h':
            type = ":/new/icons/icons/168.png";
            break;

        case 'i':
            type = ":/new/icons/icons/169.png";
            break;

        case 'j':
            type = ":/new/icons/icons/170.png";
            break;

        case 'm':
            type = ":/new/icons/icons/173.png";
            break;

        case 'n':
            type = ":/new/icons/icons/174.png";
            break;

        case 'o':
            type = ":/new/icons/icons/175.png";
            break;

        case 'p':
            type = ":/new/icons/icons/176.png";
            break;

        case 'r':
            type = ":/new/icons/icons/178.png";
            break;

        case 's':
            type = ":/new/icons/icons/179.png";
            break;

        case 't':
            type = ":/new/icons/icons/180.png";
            break;

        case 'u':
            type = ":/new/icons/icons/181.png";
            break;

        case 'v':
            type = ":/new/icons/icons/182.png";
            break;

        case 'w':
            type = ":/new/icons/icons/183.png";
            break;

        case '{':
            type = ":/new/icons/icons/187.png";
            break;
      }
    }

    return type;
}

QPointF MapDialog::ConvertPixToLatLon(QPointF *latlon)
{
    //Map is 3600 X 1800.  Each 10 pixels horizontal is a new longitude. each 10 pixels vertical is a new latitude
    //This is assuming that at the exact center of the map is the true lat-lon point (0,0)
    //Each Icon is 20x20 so to draw directly on top of each point you must offset each axis by 10.
    qreal x = ((latlon->x() * 10) + 1800 - 10); //Plus half the map size for offset.
    qreal y = ((latlon->y() * -10) + 900 - 10);  //Again offset for map size. Multiply by -10 since the pixel's grow downward

    QPointF pixCoords;
    pixCoords.setX(x);
    pixCoords.setY(y);

    return pixCoords;
}

void MapDialog::plotUser(QString callsign, QPixmap userIcon, QPointF *location)
{
    QPointF PixelLocation = ConvertPixToLatLon(location);

    foreach(basicStation* DrawnStation, scene->qlist)
    {
        if(callsign == DrawnStation->callsign)
        {
            qDebug() << "Duplicate station detected!";
            qreal oldLon = DrawnStation->pixmapItem->x();
            qreal oldLat = DrawnStation->pixmapItem->y();
            scene->qlist.removeOne(DrawnStation);
            scene->removeItem(DrawnStation->pixmapItem);

            if(oldLon != PixelLocation.x() && oldLat != PixelLocation.y())
            {
                QGraphicsLineItem *line = new QGraphicsLineItem();
                line->setLine(oldLon, oldLat, PixelLocation.x(), PixelLocation.y());

                scene->addItem(line);
                DrawnStation->traceList.append(line);
            }
        }
    }

    QGraphicsPixmapItem *User = new QGraphicsPixmapItem();
    User->setPixmap(userIcon);
    User->setX(PixelLocation.x());
    User->setY(PixelLocation.y());

    basicStation *UserStation = new basicStation();
    UserStation->callsign = callsign;
    UserStation->pixmapItem = User;

    UserStation->pixmapItem->scale(ZoomLevel, ZoomLevel);

    scene->qlist.append(UserStation);
    scene->addItem(UserStation->pixmapItem);
}

void MapDialog::clearStation(QString callsign)
{
    foreach(basicStation* DrawnStation, scene->qlist)
    {
        if(DrawnStation->callsign == callsign)
        {
            scene->removeItem(DrawnStation->pixmapItem);
            foreach(QGraphicsLineItem* lines, DrawnStation->traceList)
            {
                scene->removeItem(lines);
            }
        }
    }
}

MapDialog::~MapDialog()
{
    delete ui;
}
